﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Web;
using System.IO;
using UploadDocLib01.ErrorHandlers;

namespace UploadDocLib01.Utilities
{
    public static class ListUtils
    {

        public static bool isFieldValueEmpty(object value)
        {
            if (value is SPFieldLookupValueCollection)
            {
                if (((SPFieldLookupValueCollection)value).Count == 0)
                {
                    return true;
                }
            }
            else
            {
                if (value == null) return true;
            }
            return false;
        }
        public static bool HasView(this SPList list, string sViewName)
        {
            for (int v = 0; v < list.Views.Count; v++)
            {
                if (list.Views[v].Title == sViewName)
                    return true;
            }
            return false;
        }

        /// <summary>
        /// Gets an SPList based on the url to the list
        /// </summary>
        /// <param name="listUrl">Full url to the list</param>
        /// <returns>SPList object, null if list is not found</returns>
        public static SPList GetListByUrl(string listUrl)
        {
            SPList list = null;

            try
            {
                using (SPSite site = new SPSite(listUrl))
                {
                    if (site != null)
                    {
                        // Strip off the site url, leaving the rest
                        // We'll use this to open the web
                        string webUrl = listUrl.Substring(site.Url.Length);

                        // Strip off anything after /forms/
                        int formsPos = webUrl.IndexOf("/forms/", 0, StringComparison.InvariantCultureIgnoreCase);
                        if (formsPos >= 0)
                        {
                            webUrl = webUrl.Substring(0, webUrl.LastIndexOf('/', formsPos));
                        }

                        // Strip off anything after /lists/
                        int listPos = webUrl.IndexOf("/lists/", 0, StringComparison.InvariantCultureIgnoreCase);
                        if (listPos >= 0)
                        {
                            // Must be a custom list
                            // Strip off anything after /lists/
                            webUrl = webUrl.Substring(0, webUrl.LastIndexOf('/', listPos));
                        }
                        else
                        {
                            // No lists, must be a document library.
                            // Strip off the document library name
                            webUrl = webUrl.Substring(0, webUrl.LastIndexOf('/'));
                        }

                        // Get the web site
                        using (SPWeb web = site.OpenWeb(webUrl))
                        {
                            if (web != null)
                            {
                                // Initialize the web (avoids COM exceptions)
                                string title = web.Title;

                                // Strip off the relative list Url
                                // Form the full path to the list
                                //string relativeListUrl = listUrl.Substring(web.Url.Length);
                                //string url = SPUrlUtility.CombineUrl(web.Url, relativeListUrl);

                                // Get the list
                                list = web.GetList(listUrl);
                            }
                        }
                    }
                }
            }
            catch { }

            return list;
        }

        //-------Additional utils-------------------------------------------------------------------------------------
        public static string GetDateFormatForQuery(DateTime dt)
        {
            return Microsoft.SharePoint.Utilities.SPUtility.CreateISO8601DateTimeFromSystemDateTime(dt);
        }

        public static string GetListFieldValueByCondition(SPList list, string cond_field_name, object cond_field_value, string ret_field_name)
        {
            SPListItem sp_result = null;
            string result = null;
            sp_result = GetListSingleElementByCondition(list, cond_field_name, cond_field_value);
            result = GetFieldValueString(sp_result, ret_field_name);
            return result;
        }

        public static SPListItem GetListSingleElementByCondition(SPList list, string field_name, object field_value)
        {
            SPListItem result = null;
            SPListItemCollection items = GetListElementsByCondition(list, field_name, field_value, "=");
            foreach (SPListItem cur in items)
            {
                result = cur;
            }
            return result;
        }

        public static SPListItemCollection GetListElementsByCondition(SPList list, string field_name, object field_value, string condition)
        {
            return SelectItemCollection(list, field_name, field_value, condition);
        }

        public static SPList GetListByPath(string fulllistpath, SPContext spCntx) /* fulllistpath in format: /web1/web2/Lists/listpath  */
        {
            string web = String.Empty;
            string listpath = String.Empty;

            List<string> path_list = new List<string>();
            char[] charSeparators = new char[] { '/' };
            string[] path = fulllistpath.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);
            bool nextvalue = false;
            foreach (string cur in path)
            {
                if (nextvalue)
                {
                    listpath = cur;
                }
                else
                {
                    if (cur == "Lists")
                    {
                        nextvalue = true;
                    }
                    else
                    {
                        web += "/" + cur;
                    }
                }
            }

            SPSite SPsite = null;
            SPWeb SPweb = null;
            SPList SPlist = null;
            try
            {
                SPsite = spCntx.Site;
                if (web != "")
                    SPweb = SPsite.OpenWeb(web);
                else
                    SPweb = SPsite.OpenWeb();
                string listFullUrl = web + "/Lists/" + listpath;
                SPlist = SPweb.GetList(listFullUrl);
            }
            catch (Exception ex)
            {
                Logger.LogError("ListUtils.GetListByPath: " + ex.ToString());
            }
            finally
            {

            }
            return SPlist;
        }

        public static SPList GetOneListByPath(string fulllistpath, SPContext spCntx)
        {
            SPList list = null;
            try
            {
                list = spCntx.Web.GetList(fulllistpath);
            }
            catch (Exception ex)
            {
                Logger.LogError("ListUtils.GetListByPath: " + ex.ToString());
            }
            return list;
        }

        public static string GetListDisplayName(SPWeb web, string url_name)
        {
            string list_title_name = "";
            foreach (SPList cur in web.Lists)
            {
                string[] url_list_name = cur.RootFolder.ToString().Split('/');
                int pos = (url_list_name.Length == 2) ? 1 : 0;
                if (url_list_name[pos] == url_name)
                {
                    list_title_name = cur.Title;
                    break;
                }
            }
            return list_title_name;
        }

        public static string GetFieldTypeAsString(SPList list, string disp_name)
        {
            string result = "";
            if (disp_name == "ID")
            {
                result = "Counter";
            }
            else
            {
                result = list.Fields[disp_name].TypeAsString;
            }
            return result;
        }

        public static string GetFieldInernalName(SPList list, string disp_name)
        {
            string name;
            try
            {
                if (disp_name == "ID")
                {
                    name = "ID";
                }
                else
                {
                    name = list.Fields[disp_name].InternalName;
                }
            }
            catch (Exception ex)
            {
                name = "";
                Logger.LogError("ListUtils.GetFieldInernalName: " + ex.ToString());
            }
            return name;
        }

        public static object GetFieldValueObject(SPListItem item, params string[] args)
        {
            object result = null;
            string fieldname = args[0];
            Guid myGuid = item.ParentList.Fields.GetFieldByInternalName(fieldname).Id;
            try
            {
                if (item.Fields.ContainsField(fieldname))
                {
                    result = item[myGuid];
                }
                else
                {
                    result = "";
                }
            }
            catch (Exception ex)
            {
                result = "";
                Logger.LogError("ListUtils.GetFieldValueObject: " + ex.ToString());
            }

            return result;
        }

        public static DateTime GetFieldValueDate(SPListItem item, params string[] args)
        {
            DateTime result = new DateTime();
            string fieldname = args[0];
            Guid myGuid = item.ParentList.Fields.GetFieldByInternalName(fieldname).Id;
            string fieldtype = "";
            try
            {
                if (item.Fields.ContainsField(fieldname))
                {
                    if (fieldname == "ID")
                    {
                        fieldtype = "ID";
                    }
                    else
                    {
                        fieldtype = item.Fields[myGuid].TypeAsString;
                    }
                    switch (fieldtype)
                    {
                        case "DateTime":
                            {
                                result = ((DateTime)item[fieldname]).Date;
                            } break;
                    };
                }
                else
                {
                    result = new DateTime();
                }
            }
            catch (Exception ex)
            {
                result = new DateTime();
                Logger.LogError("ListUtils.GetFieldValueDate: " + ex.ToString());
            }
            return result;
        }

        public static string GetFieldValueString(SPListItem item, params string[] args)
        {
            string result = "";
            string fieldname = args[0];
            string fieldtype = "";
            Guid myGuid = item.ParentList.Fields.GetFieldByInternalName(fieldname).Id;
            //list.Items[0][id];
            try
            {
                if (item.Fields.ContainsField(fieldname))
                {
                    if (fieldname == "ID")
                    {
                        fieldtype = "ID";
                    }
                    else
                    {
                        fieldtype = item.Fields[myGuid].TypeAsString;
                    }
                    switch (fieldtype)
                    {
                        //-----------------------------------------------------------------------------------
                        case "DateTime":
                            {
                                if (args.Length > 1)
                                {
                                    string param = args[1];
                                    switch (param)
                                    {
                                        case "Date":
                                            {
                                                result = ((DateTime)item[myGuid]).ToShortDateString();
                                            } break;
                                        case "Time":
                                            {
                                                result = ((DateTime)item[myGuid]).ToShortTimeString();
                                            } break;
                                        case "HH:":
                                            {
                                                result = ((DateTime)item[myGuid]).Hour.ToString("00");
                                            } break;
                                        case ":MM":
                                            {
                                                result = ((DateTime)item[myGuid]).Minute.ToString("00");
                                            } break;
                                        case "H:MM":
                                            {
                                                result = ((DateTime)item[myGuid]).Hour.ToString() + ":" + ((DateTime)item[myGuid]).Minute.ToString("00");
                                            } break;
                                        case "HH:MM":
                                            {
                                                result = ((DateTime)item[myGuid]).Hour.ToString("00") + ":" + ((DateTime)item[myGuid]).Minute.ToString("00");
                                            } break;
                                        case "ddmmyy":
                                            {
                                                result = ((DateTime)item[myGuid]).Day.ToString("00") + "." + ((DateTime)item[myGuid]).Month.ToString("00") + "." + ((DateTime)item[myGuid]).Year.ToString("0000");
                                            } break;
                                        case "DD":
                                            {
                                                result = ((DateTime)item[myGuid]).Day.ToString("00");
                                            } break;
                                        case "MM":
                                            {
                                                result = ((DateTime)item[myGuid]).Month.ToString();
                                            } break;
                                        case "YYYY":
                                            {
                                                result = ((DateTime)item[myGuid]).Year.ToString("0000");
                                            } break;
                                        default:
                                            {
                                                result = ((DateTime)item[myGuid]).Date.ToString(param);
                                            } break;
                                    };
                                }
                                else
                                {
                                    result = ((DateTime)item[myGuid]).Date.ToString();
                                }
                            } break;
                        //-----------------------------------------------------------------------------------
                        case "ID":
                            {
                                result = (item as SPListItem).ID.ToString();
                            } break;
                        //-----------------------------------------------------------------------------------
                        case "URL":
                            {
                                SPFieldUrlValue lfield = new SPFieldUrlValue(item[myGuid].ToString());

                                string type = "Url";
                                if (args.Length > 1)
                                {
                                    type = args[1];
                                }

                                switch (type)
                                {
                                    case "Url":
                                        {

                                            result = lfield.Url.ToString();// lfield.GetFieldValueAsText(item[myGuid]);
                                        } break;
                                    case "Des":
                                        {
                                            result = lfield.Description.ToString();
                                        } break;
                                    default:
                                        {
                                            result = "";
                                        } break;
                                }

                            } break;
                        //-----------------------------------------------------------------------------------
                        case "User":
                        case "Lookup":
                            {
                                SPFieldLookup lfield;
                                string type = "Value";
                                if (args.Length > 1)
                                {
                                    type = args[1];
                                }

                                switch (type)
                                {
                                    case "Value":
                                        {
                                            lfield = item.Fields[myGuid] as SPFieldLookup;
                                            result = lfield.GetFieldValueAsText(item[myGuid]);
                                        } break;
                                    case "Key":
                                        {
                                            result = item[myGuid].ToString().Split(';')[0];
                                        } break;
                                    default:
                                        {
                                            result = "";
                                        } break;
                                }

                            } break;
                        //-----------------------------------------------------------------------------------
                        default:
                            {
                                result = item[myGuid].ToString();
                            } break;
                    };
                }
                else
                {
                    result = "";
                }
            }
            catch (Exception ex)
            {
                result = "";
                Logger.LogError("ListUtils.GetFieldValueString: " + ex.ToString());
            }
            return result;
        }

        public static SPListItemCollection SelectItemCollection(SPList list, string field_name, object field_value, string condition)
        {
            SPListItemCollection result;
            string relation = "";
            switch (condition)
            {
                case "=":
                    {
                        relation = "<Eq>;</Eq>";
                    } break;
                case ">":
                    {

                    } break;
                case "<":
                    {

                    } break;

                case ">=":
                    {

                    } break;
                case "<=":
                    {

                    } break;
            }
            string datavalue = "";
            string datatype = "";
            string fieldtype = GetFieldTypeAsString(list, field_name);

            switch (fieldtype)
            {
                case "User":
                case "Text":
                    {
                        datavalue = string.Format("{0}", (string)field_value);
                        if (datavalue == "System.Security.Principal.WindowsPrincipal")
                        {
                            datavalue = (field_value as System.Security.Principal.WindowsPrincipal).Identity.Name;
                        }
                        datatype = fieldtype;
                    } break;
                case "Boolean":
                    {
                        datavalue = ((string)field_value == "False") ? "0" : "1";
                        datatype = fieldtype;
                    } break;
                case "Counter":
                    {
                        datavalue = string.Format("{0}", field_value);
                        datatype = "Text";
                    } break;
                case "Choice":
                    {
                        datavalue = string.Format("{0}", field_value);
                        datatype = "Choice";
                    } break;
            }


            string strQuery = string.Format(@"
<Where>
    {0}
        <FieldRef Name='{2}'/><Value Type='{4}'>{3}</Value>
    {1}
</Where>", relation.Split(';')[0],
            relation.Split(';')[1],
            ListUtils.GetFieldInernalName(list, field_name),
            datavalue,
            datatype);

            SPQuery spQuery = new SPQuery();
            spQuery.Query = strQuery;
            result = list.GetItems(spQuery);
            return result;
        }

        public static string RandomString(int size, bool lowerCase)
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            if (lowerCase)
                return builder.ToString().ToLower();
            return builder.ToString();
        }

        public static int TryToParse(string value)
        {
            int number;
            int number1 = 0;
            bool result = int.TryParse(value, out number);
            if (result)
            {
                number1 = number;
            }
            else
            {
                number1 = 0;
            }
            return number1;
        }


        /// <summary>
        /// Helper method
        /// </summary>       
        public static string LeftString(string str, int len)
        {
            if (str.Length <= len)
                return str;
            int min_len = Math.Min(str.Length, len);
            string result = str.Substring(0, min_len);
            int space_pos = result.LastIndexOf(' ');
            if (space_pos > 0)
            {
                result = result.Substring(0, space_pos);
            }
            return result;
        }
        public static string LeftString(string str, int len, bool endings)
        {
            if (str.Length <= len)
                return str;
            int min_len = Math.Min(str.Length, len);
            string result = str.Substring(0, min_len);
            int space_pos = result.LastIndexOf(' ');
            if (space_pos > 0)
            {
                result = result.Substring(0, space_pos);
            }
            if (endings)
                result = result + "...";
            return result;
        }

        /// <summary>
        /// Get thumbnail url of image
        /// </summary>
        public static string GetThumbnailURL(string img_URL_01)
        {
            string tmp_imageURL = img_URL_01;
            try
            {
                Uri uri = new Uri(img_URL_01);
                string filename = Path.GetFileName(uri.LocalPath);
                string filenameWOext = Path.GetFileNameWithoutExtension(uri.LocalPath);
                string ext = Path.GetExtension(uri.LocalPath);
                string thumbnailURL = img_URL_01.Replace(filename, String.Empty) + "_t/" + filenameWOext + "_" + ext.Replace(".", String.Empty) + ".jpg";
                tmp_imageURL = thumbnailURL;
                return tmp_imageURL;
            }
            catch { return img_URL_01; }

        }
        //-------------------------------------------------------------------------------------------------------
    }
}
